#include <string.h>
#include "gkt_debug.h"
#include "gkt_os.h"
#include "gkt_voice.h"
#include "gkt_event.h"
#include "gkt_window.h"
#include "gkt_language.h"

#if GKT_CONFIG_VOICE_OUTPUT_ENABLE

typedef union {
	uint32_t	id;
	uint32_t	combined_id;
	gkt_voice_meta_id_t	meta_id;

	const void	*ids;
	const uint32_t	*combined_ids;
	const gkt_voice_meta_id_t	*meta_ids;
} window_voice_id_attr_u;

typedef struct {
	int	request_id;
	gkt_window_id_t window_id;	

	uint32_t	flags;
	uint32_t	ids_num;
	window_voice_id_attr_u	id_attr;
	gkt_voice_output_playback_attr_s	playback_attr;
} window_voice_item_s;

#define WINDOW_VOICE_F_REPEAT_LISTEN_PLAYED	(1U << GKT_WINDOW_VOICE_F_INNER_SHIFT)
#define WINDOW_VOICE_F_INNER_PLAY_RESET_MASK	\
	WINDOW_VOICE_F_REPEAT_LISTEN_PLAYED
#define WINDOW_VOICE_F_COMBINED	(1U << (GKT_WINDOW_VOICE_F_INNER_SHIFT + 4))

#ifdef GKT_CONFIG_WINDOW_VOICE_INDEX_META_IDS_MAXNUM
#define WINDOW_VOICE_INDEX_META_IDS_MAXNUM	\
	GKT_CONFIG_WINDOW_VOICE_INDEX_META_IDS_MAXNUM
#else
#define WINDOW_VOICE_INDEX_META_IDS_MAXNUM	16
#endif

typedef struct _window_voice {
	uint32_t	combined_nums[GKT_LANG_MAX];
	const gkt_voice_combined_attr_s	*combined_attrs_table[GKT_LANG_MAX];
	uint32_t	common_combined_ids[GKT_WINDOW_VOICE_COMMON_MAX];
	gkt_voice_meta_id_t	index_hint_meta_ids[GKT_WINDOW_VOICE_INDEX_HINT_META_ID_MAX];

	int	mute_enable;
	int	playing;
	int	request_id;	/* user base request id */
	uint32_t	current_seq;	/* current sequence number */
	uint32_t	current_index;	/* current item index */
	uint32_t	multiple_index;

	window_voice_item_s	*current;
	window_voice_item_s	*pendding;
	window_voice_item_s	items[2];

	gkt_voice_meta_id_t	index_meta_ids[WINDOW_VOICE_INDEX_META_IDS_MAXNUM + 4];
	gkt_voice_combined_attr_s	tmp_combined_attr;
} window_voice_s;
static window_voice_s s_window_voice;

#define WINDOW_VOICE_TIMER_TIMEOUT	GKT_WINDOW_TIMER_MANAGE_TYPE_ID(VOICE, 0)

#define WINDOW_VOICE_EVTDATA_CURRENT_SEQ	0
#define WINDOW_VOICE_EVENT_PUT_TIMEOUT	100

static const uint32_t sc_window_voice_state_2_event_map[GKT_VOICE_OUTPUT_ST_MAX] = {
	GKT_WINDOW_VOICE_EVENT_PLAY_END,
	GKT_WINDOW_VOICE_EVENT_PLAY_ERROR
};
static void window_voice_callback(uint32_t current_seq, 
				int state)
{
	gkt_event_s event;

	gkt_trace("window_voice_callback: seq(%u), state(%d)\n",
			current_seq, state);

	if (state < GKT_VOICE_OUTPUT_ST_MAX) {
		event.window_id = -1;
		event.flags = 0;
		event.major_type = GKT_EVENT_VOICE;
		event.minor_type = sc_window_voice_state_2_event_map[state];
		event.data[WINDOW_VOICE_EVTDATA_CURRENT_SEQ] = current_seq;
		gkt_event_put(&event, WINDOW_VOICE_EVENT_PUT_TIMEOUT);
	}
}

static const uint32_t sc_window_voice_event_flag_masks[GKT_WINDOW_VOICE_EVENT_MAX] = {
	GKT_WINDOW_VOICE_F_NOTIFY_START,
	GKT_WINDOW_VOICE_F_NOTIFY_END,
	GKT_WINDOW_VOICE_F_NOTIFY_ERROR,
	GKT_WINDOW_VOICE_F_NOTIFY_END
};
static void window_voice_event_notify(uint32_t event)
{
	gkt_window_s *window;
	gkt_widget_s *widget;
	uint32_t event_flag_masks, widget_id;

	gkt_trace("window_voice_event_notify: event(%u), flags(0x%x)\n", 
				event, s_window_voice.current->flags);

	event_flag_masks = sc_window_voice_event_flag_masks[event];
	if ((s_window_voice.current->flags & event_flag_masks)
		&& (s_window_voice.current->window_id >= GKT_WINDOW_ID_USER_BASE)) 
	{		
		window = gkt_window_find(s_window_voice.current->window_id);
		if (__UNLIKELY(!window)) {
			gkt_error("window_voice_event: window unknown!\n");
			return;
		}

		if (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_WIDGET) {
			widget_id = (s_window_voice.current->flags >> GKT_WINDOW_VOICE_F_WIDGET_ID_SHIFT)
						& ((1U << GKT_WINDOW_VOICE_F_WIDGET_ID_BITS) - 1);
			if (__LIKELY((uint16_t)widget_id < window->desc->widget_nums)) {
				widget = window->widgets + widget_id;
				gkt_widget_event_dispatch(widget, GKT_EVENT_VOICE, event, 
					(uint32_t)s_window_voice.current->request_id);
			}
		}
		else {
			gkt_window_custom_event_handle(window, 
					GKT_EVENT_VOICE, event, 
					(uint32_t)s_window_voice.current->request_id, 0);
		}
	}
}

static void window_voice_stop(void)
{
	s_window_voice.playing = 0;
	gkt_voice_output_stop();
	gkt_window_timer_clear(WINDOW_VOICE_TIMER_TIMEOUT);
}

static void window_voice_timeout_set(uint32_t duration_ms)
{
	uint32_t voice_flags = 0;

	if ((s_window_voice.current->flags & GKT_WINDOW_VOICE_F_UNINTERRUPT)
		|| (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_DETACHED))
	{
		voice_flags |= GKT_WINDOW_TIMER_F_DETACHED;
	}

	gkt_window_timer_set(WINDOW_VOICE_TIMER_TIMEOUT,
			duration_ms, voice_flags, s_window_voice.current_seq);
}

#define WINDOW_VOICE_TIMEOUT_DELAY_MS	100
static int window_voice_play_attr(const gkt_voice_combined_attr_s *combined_attr)
{
	uint32_t duration_ms;
	int retval;

	s_window_voice.playing = 1;
	s_window_voice.current_seq++;

	gkt_trace("window_voice_play_attr: current_seq(%u)\n", 
		s_window_voice.current_seq);

#if !defined(GKT_CONFIG_WINDOW_VOICE_MUTE_DISABLE) \
	|| !GKT_CONFIG_WINDOW_VOICE_MUTE_DISABLE
	if (!s_window_voice.mute_enable
		|| !(s_window_voice.current->flags & GKT_WINDOW_VOICE_F_MUTE_AFFECTED))
	{
		duration_ms = 0;
		retval = gkt_voice_output_play(combined_attr, 
						&s_window_voice.current->playback_attr, 
						s_window_voice.current_seq, &duration_ms);
		if (GKT_SUCCESS == retval)
			window_voice_timeout_set(duration_ms + WINDOW_VOICE_TIMEOUT_DELAY_MS);
		else {
			s_window_voice.playing = 0;
			gkt_error("widnow_voice_play_current_attr: failed(%d)\n", retval);
		}
	}
	else {
		duration_ms = gkt_voice_get_duration_ms(combined_attr, 
							&s_window_voice.current->playback_attr);
		if (duration_ms > 0) {
			retval = GKT_SUCCESS;
			window_voice_timeout_set(duration_ms);
		}
		else {
			retval = GKT_EPARAM;
			s_window_voice.playing = 0;
			gkt_error("widnow_voice_play_current_attr: failed\n");
		}
	}
#else
	duration_ms = 0;
	retval = gkt_voice_output_play(combined_attr, 
					&s_window_voice.current->playback_attr, 
					s_window_voice.current_seq, &duration_ms);
	if (GKT_SUCCESS == retval)
		window_voice_timeout_set(duration_ms + WINDOW_VOICE_TIMEOUT_DELAY_MS);
	else {
		s_window_voice.playing = 0;
		gkt_error("widnow_voice_play_current_attr: failed(%d)\n", retval);
	}
#endif

	return retval;
}

static const gkt_voice_combined_attr_s *window_voice_multiple_build_attr(
				const gkt_voice_combined_attr_s *combined_attr,
				uint32_t index)
{
	uint32_t valid_meta_nums, i;

	if (__LIKELY(combined_attr->meta_nums && combined_attr->meta_ids)) {
		valid_meta_nums = combined_attr->meta_nums;
		if (valid_meta_nums > WINDOW_VOICE_INDEX_META_IDS_MAXNUM)
			valid_meta_nums = WINDOW_VOICE_INDEX_META_IDS_MAXNUM;

		if (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_TAIL_PPI) {
			for (i = 0; i < valid_meta_nums; i++)
				s_window_voice.index_meta_ids[i] = combined_attr->meta_ids[i];
			//s_window_voice.index_meta_ids[i++] = 
				//s_window_voice.index_hint_meta_ids[GKT_WINDOW_VOICE_INDEX_HINT_META_ID_PRESS];
			s_window_voice.index_meta_ids[i++] = 
				s_window_voice.index_hint_meta_ids[index];
		}
		else if (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_HEAD_INDEX) {
			s_window_voice.index_meta_ids[0] = 
				s_window_voice.index_hint_meta_ids[index];
			for (i = 0; i < valid_meta_nums; i++)
				s_window_voice.index_meta_ids[i + 1] = combined_attr->meta_ids[i];
			i++;
		}
		else
			return combined_attr;

		s_window_voice.tmp_combined_attr.meta_nums = i;
		s_window_voice.tmp_combined_attr.meta_ids = &s_window_voice.index_meta_ids[0];

		return &s_window_voice.tmp_combined_attr;
	}

	return NULL;
}

static int widnow_voice_play_current(void)
{
	const gkt_voice_combined_attr_s *combined_attr;
	uint32_t combined_id;
	int retval = -1;

	gkt_trace("window_voice_play_current: mute(%d), flags(0x%x), ids_num(%u)\n",
				s_window_voice.mute_enable, s_window_voice.current->flags,
				s_window_voice.current->ids_num);

	if (s_window_voice.current->flags & WINDOW_VOICE_F_COMBINED) {
		if ((s_window_voice.current->ids_num > 1)
			|| (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_REPEAT_LISTEN)) 
		{
			while (s_window_voice.multiple_index < s_window_voice.current->ids_num) {
				combined_id = s_window_voice.current->id_attr.combined_ids[s_window_voice.multiple_index];
				s_window_voice.multiple_index++;

				if (!combined_id || (combined_id >= s_window_voice.combined_nums[GKT_LAGNUAGE])) {
					gkt_error("widnow_voice_play_current: (%u) invalid combined_id\n", combined_id);
					continue;
				}

				combined_attr = &s_window_voice.combined_attrs_table[GKT_LAGNUAGE][combined_id];
				if (__UNLIKELY(!combined_attr->meta_nums || !combined_attr->meta_ids)) {
					gkt_error("widnow_voice_play_current: (%u) invalid combined_attr\n", combined_id);
					continue;
				}
				combined_attr = window_voice_multiple_build_attr(combined_attr, 
									s_window_voice.multiple_index);
				if (combined_attr) {
					retval = window_voice_play_attr(combined_attr);
					if (GKT_SUCCESS == retval)
						return retval;
				}
			}

#if GKT_WINDOW_VOICE_REPEAT_LISTEN
			if ((s_window_voice.current->flags & GKT_WINDOW_VOICE_F_REPEAT_LISTEN)
				&& !(s_window_voice.current->flags & WINDOW_VOICE_F_REPEAT_LISTEN_PLAYED)) 
			{
				gkt_voice_combined_attr_s repeat_listen_attr;

				s_window_voice.current->flags |= WINDOW_VOICE_F_REPEAT_LISTEN_PLAYED;

				repeat_listen_attr.meta_nums = 1;
				repeat_listen_attr.meta_ids = &s_window_voice.index_hint_meta_ids[GKT_WINDOW_VOICE_INDEX_HINT_META_ID_REPEAT_LISTEN];
				combined_attr = window_voice_multiple_build_attr(&repeat_listen_attr, 0);
				if (combined_attr) {
					retval = window_voice_play_attr(combined_attr);
					if (GKT_SUCCESS == retval)
						return retval;
				}
			}
#endif
		}
		else {
			combined_id = s_window_voice.current->id_attr.combined_id;
			combined_attr = &s_window_voice.combined_attrs_table[GKT_LAGNUAGE][combined_id];
			retval = window_voice_play_attr(combined_attr);
		}
	}
	else {
		s_window_voice.tmp_combined_attr.meta_nums = 
				s_window_voice.current->ids_num;
		s_window_voice.tmp_combined_attr.meta_ids = 
				s_window_voice.current->id_attr.meta_ids;
		retval = window_voice_play_attr(&s_window_voice.tmp_combined_attr);
	}

	return retval;
}

static void window_voice_play_pendding(void)
{
	int retval;

	if (!s_window_voice.playing) {
		if (s_window_voice.pendding) {
			s_window_voice.current_index ^= 1;
			s_window_voice.current = s_window_voice.pendding;
			s_window_voice.pendding = NULL;

			s_window_voice.current->flags &= ~WINDOW_VOICE_F_INNER_PLAY_RESET_MASK;
			s_window_voice.multiple_index = 0;

			retval = widnow_voice_play_current();
			if (GKT_SUCCESS == retval) {
				window_voice_event_notify(GKT_WINDOW_VOICE_EVENT_PLAY_START);
				return;
			}
			else {
				window_voice_event_notify(GKT_WINDOW_VOICE_EVENT_PLAY_ERROR);
				if (s_window_voice.playing)
					return;
			}
		}

		s_window_voice.current = NULL;
		gkt_window_timeout_enable("voice_play_pending - end");
	}
}

static void window_voice_save_params(int *request_id,
				const void *ids, uint32_t ids_num, uint32_t flags,
				const gkt_voice_output_playback_attr_s *playback_attr,
				window_voice_item_s *voice_item)
{
	gkt_window_s *window;

	/* save params to voice_item */
	s_window_voice.request_id++;
	if (s_window_voice.request_id < 0)
		s_window_voice.request_id = 1;
	voice_item->request_id = s_window_voice.request_id;
	if (request_id)
		*request_id = s_window_voice.request_id;
	
	window = gkt_window_find(GKT_WINDOW_ID_CURRENT);
	if (!window)
		window = gkt_window_find(GKT_WINDOW_ID_ACTIVE);
	voice_item->window_id = window ? window->desc->id : -1;

	voice_item->flags = flags;
	voice_item->ids_num = ids_num;
	voice_item->id_attr.ids = ids;
	if (playback_attr)
		voice_item->playback_attr = *playback_attr;
	else {
		voice_item->playback_attr.times = 1;
		voice_item->playback_attr.interval = 0;
	}
}

static int window_voice_play_inner(int *request_id,
				const void *ids, uint32_t ids_num, uint32_t flags,
				const gkt_voice_output_playback_attr_s *playback_attr)
{
	uint32_t item_index;
	int retval;
	if (s_window_voice.current 
		&& s_window_voice.playing) 
	{
		if (flags & GKT_WINDOW_VOICE_F_FOLLOWING) {
			if (s_window_voice.pendding
				&& (s_window_voice.pendding->flags & GKT_WINDOW_VOICE_F_RESIDENT))
			{
				gkt_error("window_voice_play_inner: RESIDENT, FORBID!\n");
				return GKT_EPERMIT;
			}
			
			item_index = s_window_voice.current_index ^ 1;
			s_window_voice.pendding = &s_window_voice.items[item_index];
			window_voice_save_params(request_id, 
					ids, ids_num, flags, playback_attr,
					s_window_voice.pendding);

			return GKT_WINDOW_VOICE_ST_PENDING;
		}
		else if (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_UNINTERRUPT) {
			gkt_info("window_voice_play_inner: UNINTERRUPT -> BUSY!\n");
			return GKT_EBUSY;
		}
		else {
			if (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_AUTO_RESTART) {
				if (s_window_voice.pendding
					&& (s_window_voice.pendding->flags & GKT_WINDOW_VOICE_F_RESIDENT))
				{
					if (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_RESIDENT) {
						gkt_error("window_voice_play_inner: RESIDENT, FORBID!\n");
						return GKT_EPERMIT;
					}
					else
						s_window_voice.current = NULL;
				}
				else {
					s_window_voice.pendding = s_window_voice.current;
					s_window_voice.current = NULL;
					s_window_voice.current_index ^= 1;
				}
			}

			window_voice_stop();
		}
	}
	else if (!s_window_voice.current)
		gkt_window_timeout_disable("voice_play - start");

	s_window_voice.current = &s_window_voice.items[s_window_voice.current_index];
	window_voice_save_params(request_id, 
				ids, ids_num, flags, playback_attr,
				s_window_voice.current);

	s_window_voice.current->flags &= ~WINDOW_VOICE_F_INNER_PLAY_RESET_MASK;
	s_window_voice.multiple_index = 0;

	retval = widnow_voice_play_current();
	if (retval != GKT_SUCCESS) {
		s_window_voice.current = NULL;
		window_voice_play_pendding();
	}

	return retval;
}

int gkt_window_voice_play(int *request_id,
			uint32_t combined_id, uint32_t flags,
			const gkt_voice_output_playback_attr_s *playback_attr)
{
	const gkt_voice_combined_attr_s *combined_attr;
	int retval;

	gkt_trace("window_voice_play: combined_id(%u), flags(0x%x)\n",
				combined_id, flags);

	if (combined_id < s_window_voice.combined_nums[GKT_LAGNUAGE]) {
		combined_attr = &s_window_voice.combined_attrs_table[GKT_LAGNUAGE][combined_id];
		if (__UNLIKELY(!combined_attr->meta_nums || !combined_attr->meta_ids)) {
			gkt_error("window_voice_play: (%u) attr invalid!\n", combined_id);
			return GKT_EPARAM;
		}

		retval = window_voice_play_inner(request_id, 
						(const void *)combined_id, 1, 
						flags | WINDOW_VOICE_F_COMBINED, playback_attr);
	}
	else {
		gkt_error("window_voice_play: combined_id(%u) overflow!\n", combined_id);
		retval = GKT_EPARAM;
	}

	return retval;
}

int gkt_window_voice_play_multiple(int *request_id,
			const uint32_t *combined_ids, uint32_t combined_ids_num, 
			uint32_t flags)
{
	int retval;

	if (combined_ids && (combined_ids_num >= 1)) {
		retval = window_voice_play_inner(request_id, 
						(const void *)combined_ids, combined_ids_num,
						flags | WINDOW_VOICE_F_COMBINED, NULL);
	}
	else
		retval = GKT_EPARAM;

	return retval;
}

void gkt_window_voice_play_common(uint32_t common_id)
{
	uint32_t combined_id;

	if (common_id < GKT_WINDOW_VOICE_COMMON_MAX) {
		combined_id = s_window_voice.common_combined_ids[common_id];
		if (combined_id > 0)
			gkt_window_voice_play(NULL, combined_id, 0, NULL);
	}
}

int gkt_window_voice_play_meta(int *request_id,
			const gkt_voice_meta_id_t *meta_ids, 
			uint32_t meta_ids_num, uint32_t flags)
{
	int retval;

	if (meta_ids && (meta_ids_num > 0)) {
		retval = window_voice_play_inner(request_id,
						(const void *)meta_ids, meta_ids_num,
						flags & (~WINDOW_VOICE_F_COMBINED), NULL);
	}
	else
		retval = GKT_EPARAM;

	return retval;
}

void gkt_window_voice_stop(uint32_t flags)
{
	uint32_t mask, masked_flags;

	gkt_trace("window_voice_stop: flags(0x%x)\n", flags);

	mask = GKT_WINDOW_VOICE_F_UNINTERRUPT | GKT_WINDOW_VOICE_F_DETACHED;

	if (s_window_voice.pendding) {
		if (!(s_window_voice.pendding->flags & GKT_WINDOW_VOICE_F_RESIDENT)) {
			masked_flags = s_window_voice.pendding->flags & mask;
			if (!masked_flags || (masked_flags & flags))
				s_window_voice.pendding = NULL;
		}
	}

	if (s_window_voice.current) {
		if (!(s_window_voice.current->flags & GKT_WINDOW_VOICE_F_RESIDENT)) {
			masked_flags = s_window_voice.current->flags & mask;
			if (!masked_flags || (masked_flags & flags)) {
				window_voice_stop();
				window_voice_play_pendding();
			}
		}
	}
}

void gkt_window_voice_stop_id(int request_id)
{
	gkt_trace("window_voice_stop: request_id(%u)\n", request_id);

	if (request_id > 0) {
		if (s_window_voice.current
			&& (s_window_voice.current->request_id == request_id)) 
		{
			window_voice_stop();
			window_voice_play_pendding();
			return;
		}

		if (s_window_voice.pendding 
			&& (s_window_voice.pendding->request_id == request_id))
		{
			s_window_voice.pendding = NULL;
		}
	}
}

uint32_t gkt_window_voice_get_duration_ms(uint32_t combined_id,
				const gkt_voice_output_playback_attr_s *playback_attr)
{
	const gkt_voice_combined_attr_s *combined_attr;
	uint32_t duration_ms = 0;

	if (combined_id < s_window_voice.combined_nums[GKT_LAGNUAGE]) {
		combined_attr = &s_window_voice.combined_attrs_table[GKT_LAGNUAGE][combined_id];
		if (combined_attr->meta_nums && combined_attr->meta_ids)
			duration_ms = gkt_voice_get_duration_ms(combined_attr, playback_attr);
		else
			gkt_error("window_voice_duration: (%u) attr invalid!\n", combined_id);
	}
	else
		gkt_error("window_voice_duration: combined_id(%u) overflow!\n", combined_id);

	return duration_ms;
}

static void window_voice_event_handler(uint32_t event)
{
	int retval;

	window_voice_stop();

	if ((s_window_voice.current->flags & WINDOW_VOICE_F_COMBINED)
		&& ((s_window_voice.current->ids_num > 1)
			|| (s_window_voice.current->flags & GKT_WINDOW_VOICE_F_REPEAT_LISTEN))) 
	{
		retval = widnow_voice_play_current();
		if (GKT_SUCCESS == retval)
			return;
	}

	window_voice_event_notify(event);
	window_voice_play_pendding();
}
static void window_voice_timer_handler(uint32_t type, 
				uint32_t current_seq)
{
	uint32_t event;

	gkt_unused(type);

	gkt_trace("window_voice_timer_handler: type(%u), current_seq(%u)\n",
				type, current_seq);

	if (s_window_voice.current
		&& (current_seq == s_window_voice.current_seq))
	{
#if !defined(GKT_CONFIG_WINDOW_VOICE_MUTE_DISABLE) \
	|| !GKT_CONFIG_WINDOW_VOICE_MUTE_DISABLE
		if (!s_window_voice.mute_enable
			|| !(s_window_voice.current->flags & GKT_WINDOW_VOICE_F_MUTE_AFFECTED))
		{
			event = GKT_WINDOW_VOICE_EVENT_PLAY_TIMEOUT;
		}
		else
			event = GKT_WINDOW_VOICE_EVENT_PLAY_END;
#else
		event = GKT_WINDOW_VOICE_EVENT_PLAY_TIMEOUT;
#endif

		window_voice_event_handler(event);
	}
}
static int gkt_window_voice_event_handler(gkt_event_s *event)
{
	gkt_trace("gkt_window_voice_event_handler: minor_type(%u), current_seq(%u / %u)\n", 
		event->minor_type, s_window_voice.current_seq, 
		event->data[WINDOW_VOICE_EVTDATA_CURRENT_SEQ]);
	
	if (s_window_voice.current
		&& (event->data[WINDOW_VOICE_EVTDATA_CURRENT_SEQ] == s_window_voice.current_seq)) 
	{
		window_voice_event_handler(event->minor_type);
	}

	return GKT_EVENT_HANDLE_COMPLETE;
}

void gkt_window_voice_config(gkt_language_e language, gkt_window_voice_config_params_s *config_params)
{
	uint32_t i;

	if (config_params 
		&& (config_params->combined_nums > 0)
		&& config_params->attrs_table)
	{
		s_window_voice.combined_nums[language] = config_params->combined_nums;
		s_window_voice.combined_attrs_table[language] = config_params->attrs_table;
		for (i = 0; i < GKT_WINDOW_VOICE_COMMON_MAX; i++)
			s_window_voice.common_combined_ids[i] = config_params->common_combined_ids[i];
		for (i = 0; i < GKT_WINDOW_VOICE_INDEX_HINT_META_ID_MAX; i++)
			s_window_voice.index_hint_meta_ids[i] = config_params->index_hint_meta_ids[i];
	}
}

void gkt_window_voice_set_mute(int mute_enable)
{
	gkt_trace("window_voice: mute %d --> %d\n", 
		s_window_voice.mute_enable, mute_enable);
	s_window_voice.mute_enable = mute_enable;
}

int gkt_window_voice_init(void)
{
	int retval;

	gkt_info("gkt_window_voice_init enter\n");
	retval = gkt_voice_init();
	if (__UNLIKELY(retval != GKT_SUCCESS)) {
		gkt_error("window_voice_init: init failed %d\n", retval);
		return retval;
	}

	gkt_voice_output_register_callback(window_voice_callback);

	gkt_window_timer_register_manage_handler(
			GKT_WINDOW_TIMER_MANAGE_VOICE,
			window_voice_timer_handler);

	return GKT_SUCCESS;
}
#else

#define gkt_window_voice_init	NULL
#define gkt_window_voice_event_handler	NULL

#endif

#define gkt_window_voice_mask	NULL

GKT_EVENT_DESC_DEFINE(VOICE, window_voice);

